import java.util.Arrays;
import java.util.Objects;

/**
 * Created with IntelliJ IDEA.
 * Description:
 * User: 23735
 * Date: 2022-10-07
 * Time: 21:53
 */
public class AnotherHashBuck<K,V> {
    @Override
    public boolean equals(Object o) {
        if (this == o) return true;
        if (o == null || getClass() != o.getClass()) return false;
        AnotherHashBuck<?, ?> that = (AnotherHashBuck<?, ?>) o;
        return usedSize == that.usedSize && Arrays.equals(array, that.array);
    }

    @Override
    public int hashCode() {
        int result = Objects.hash(usedSize);
        result = 31 * result + Arrays.hashCode(array);
        return result;
    }

    static class Node <K ,V>{
        public K key;
        public V value;
        public Node<K,V> next;
        public Node(K key,V value){
            this.key=key;
            this.value=value;
        }
    }

    public Node<K,V>[] array=(Node<K,V>[])new Node[10];;
    public int usedSize;
    public static final double DEFAULT_LOAD_FACTOR=0.75;

    /**
     * 放置元素
     * @param key
     * @param value
     */
    public void put(K key,V value){
        //找位置
        int hash=key.hashCode() % array.length;
        //看看是否有key值相同的情况,有就更新value
        Node<K,V> cur=array[hash];
        while(cur!=null){
            //有key值相同的情况
            //不能用==得用equals
            if(cur.key.equals(key)){
                cur.value=value;
                return ;
            }
            cur=cur.next;
        }
        //没有key值与之相同,头插
        if(array[hash]==null){
            //该位置没有节点
            array[hash]=new Node<K,V>(key,value);
        }else{
            Node<K,V> newNode=new Node<K,V>(key,value);
            newNode.next=array[hash];
            array[hash]=newNode;
        }
        this.usedSize++;
        //检查负载因子
        double loadFactor=1.0*usedSize/array.length;
        //如果大于负载因子需要重新哈希
        if(loadFactor>DEFAULT_LOAD_FACTOR){
            //先扩容
            Node<K,V>[] newArray=(Node<K,V>[])new Node[array.length*2];
            //重新哈希
            for (int i = 0; i < array.length; i++) {
                Node<K,V> temp=array[i];
                while(temp!=null){
                    Node<K,V> tempNext=temp.next;
                    Node<K,V> node=temp;
                    int newHash=node.key.hashCode()%newArray.length;
                    node.next=newArray[newHash];
                    newArray[newHash]=node;
                    temp=tempNext;
                }
            }
            //数组交换为新的数组
            this.array=newArray;
        }

    }

    /**
     * 根据key值获取value
     * @param key
     * @return
     */
    public V get(K key){
        int hash=key.hashCode()%this.array.length;
        Node<K,V> cur=array[hash];
        while(cur!=null){
            //不能用==得用equals
            if(cur.key.equals(key)){
                return cur.value;
            }
            cur=cur.next;
        }
        return null;
    }
}
